package com.lenovo.translatetext.utils;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.util.Log;
import com.lenovo.translatetext.entity.DetectResult;
import com.optimaize.langdetect.LanguageDetector;
import com.optimaize.langdetect.LanguageDetectorBuilder;
import com.optimaize.langdetect.ngram.NgramExtractors;
import com.optimaize.langdetect.profiles.LanguageProfile;
import com.optimaize.langdetect.profiles.LanguageProfileReader;
import com.optimaize.langdetect.text.CommonTextObjectFactories;
import com.optimaize.langdetect.text.TextObjectFactory;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import static com.lenovo.translatetext.utils.DetectUtils.languageDetectByApi;
import static com.lenovo.translatetext.utils.DetectUtils.languageDetectByJar;

/**
 * @ProjectName: Translation
 * @Package: com.lenovo.translatetext.utils
 * @ClassName: FileUtils
 * @Description: FileUtils类作用描述
 * @Author: kgzhou
 * @CreateDate: 2019/4/28 10:32
 * @UpdateUser: kgzhou
 * @UpdateDate: 2019/4/28 10:32
 * @UpdateRemark: 更新说明：
 * @Version: 1.0
 */
public class FileUtils {
    private static final String TAG = FileUtils.class.getSimpleName();

    /**
     * 获取asset下文件生成流
     *
     * @param fileName
     * @return
     */
    public static InputStream getAssetResourcesFileInputStream(String fileName) {
        return Thread.currentThread().getContextClassLoader().getResourceAsStream("assets/" + fileName);
    }

    /**
     * 读取Excel文件并且解析
     */
    public static List<DetectResult> readExcelAndDetect(String path, Boolean isOnline) throws IOException {
        Log.d(TAG, "readExcel: path---->" + path);
        List<DetectResult> data = new ArrayList<>();

        File file = new File(path);
        if (file.exists() && file.isFile()) {
            Log.d(TAG, "readExcel: +++++++++++++++++++++++++++++++++++++");
        }
        Log.d(TAG, "readExcel: File---->" + file.toString());
        String fileName = file.getName();
        Log.d(TAG, "readExcel: fileName--->" + fileName);

        String compareCode = fileName.split("\\.")[0].trim();

        InputStream fileInputStream = new FileInputStream(file);

        HSSFWorkbook wb = new HSSFWorkbook(fileInputStream);
        //Workbook wb = WorkbookFactory.create(fileInputStream);
        HSSFSheet sheet = wb.getSheetAt(0);
        Row row = null;
        Cell cell = null;
        DetectResult detectResult = null;
        StringBuilder builder=null;
        for (int i = 1; i <= sheet.getLastRowNum(); i++) {
            row = sheet.getRow(i);
            cell = row.getCell(1);
            Log.d(TAG, "readExcel: ToBeTranslated----->" + cell);
            builder=new StringBuilder();
            builder.append(cell.toString());
            //将字符重复3遍，提高准确率
            if(cell.toString().length()<50){
                for(int j=0;j<3;j++){
                    builder.append(cell.toString());
                }
            }
            //进行在线/离线解析
            if (isOnline) {
                detectResult = languageDetectByApi(builder.toString(), compareCode);
            } else {
                detectResult = languageDetectByJar(builder.toString(), compareCode);
            }
            detectResult.setOriginalText(row.getCell(0).toString());
            detectResult.setCompareText(cell.toString());
            data.add(detectResult);
        }
        wb.close();
        return data;
    }

    /**
     * 将结果输出到Excel表中
     *
     * @param results
     * @param filePath
     * @throws Exception
     */
    public static void writeToExcel(List<DetectResult> results, String filePath) throws Exception {
        HSSFWorkbook workbook = new HSSFWorkbook();
        HSSFSheet sheet = workbook.createSheet("Detect Result");
        setTitle(sheet);
        DetectResult result = null;
        for (int i = 0; i < results.size(); i++) {
            result = results.get(i);
            Row row = sheet.createRow(i + 1);
            row.createCell(0).setCellValue(result.getOriginalText());
            row.createCell(1).setCellValue(result.getCompareText());
            row.createCell(2).setCellValue(result.getCode());
            row.createCell(3).setCellValue(result.getPass());
            row.createCell(4).setCellValue(result.getConfidence());
            row.createCell(5).setCellValue(result.getReliable());
        }
        File temp=new File(filePath);
        Log.d(TAG, "writeToExcel: FileName--->"+temp.getName());
        File file = new File(Environment.getExternalStorageDirectory(), temp.getName());
        FileUtils.writeExcel(workbook, file);
    }

    private static void setTitle(HSSFSheet sheet) {
        Row title = sheet.createRow(0);
        Cell originalText = title.createCell(0);
        originalText.setCellValue("OriginalText");
        Cell compareText = title.createCell(1);
        compareText.setCellValue("CompareText");
        Cell code = title.createCell(2);
        code.setCellValue("Code");
        Cell detectResult = title.createCell(3);
        detectResult.setCellValue("DetectResult(Pass/Fail)");
        Cell confidence = title.createCell(4);
        confidence.setCellValue("Confidence");
        Cell isRealiable = title.createCell(5);
        isRealiable.setCellValue("Is Realiable(True/False)");
    }

    /**
     * 通过Uri获取路径
     *
     * @param context
     * @param uri
     * @return
     */
    public static String getFilePathByUri(Context context, Uri uri) {
        String path = null;
        // 以 file:// 开头的
        if (ContentResolver.SCHEME_FILE.equals(uri.getScheme())) {
            path = uri.getPath();
            return path;
        }
        // 以 content:// 开头的，比如 content://media/extenral/images/media/17766
        if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme()) && Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
            Cursor cursor = context.getContentResolver().query(uri, new String[]{MediaStore.Images.Media.DATA}, null,
                    null, null);
            if (cursor != null) {
                if (cursor.moveToFirst()) {
                    int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                    if (columnIndex > -1) {
                        path = cursor.getString(columnIndex);
                    }
                }
                cursor.close();
            }
            return path;
        }
        // 4.4及之后的 是以 content:// 开头的，比如 content://com.android.providers.media.documents/document/image%3A235700
        if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme()) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            if (DocumentsContract.isDocumentUri(context, uri)) {
                if (isExternalStorageDocument(uri)) {
                    // ExternalStorageProvider
                    final String docId = DocumentsContract.getDocumentId(uri);
                    final String[] split = docId.split(":");
                    final String type = split[0];
                    if ("primary".equalsIgnoreCase(type)) {
                        path = Environment.getExternalStorageDirectory() + "/" + split[1];
                        return path;
                    }
                } else if (isDownloadsDocument(uri)) {
                    // DownloadsProvider
                    final String id = DocumentsContract.getDocumentId(uri);
                    final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),
                            Long.valueOf(id));
                    path = getDataColumn(context, contentUri, null, null);
                    return path;
                } else if (isMediaDocument(uri)) {
                    // MediaProvider
                    final String docId = DocumentsContract.getDocumentId(uri);
                    final String[] split = docId.split(":");
                    final String type = split[0];
                    Uri contentUri = null;
                    if ("image".equals(type)) {
                        contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                    } else if ("video".equals(type)) {
                        contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                    } else if ("audio".equals(type)) {
                        contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                    }
                    final String selection = "_id=?";
                    final String[] selectionArgs = new String[]{split[1]};
                    path = getDataColumn(context, contentUri, selection, selectionArgs);
                    return path;
                }
            }
        }
        return null;
    }

    private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = {column};
        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
            if (cursor != null && cursor.moveToFirst()) {
                final int column_index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(column_index);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }

    private static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    private static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    private static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }


    private static LanguageDetector languageDetector = null;

    //单例模式延迟加载获取LanguageDetect对象
    public static LanguageDetector getLanguageDetector() throws IOException {

        if (languageDetector == null) {
            synchronized (FileUtils.class) {
                if (languageDetector == null) {
                    //load all languages:
                    List<LanguageProfile> languageProfiles = new LanguageProfileReader().readAllBuiltIn();
                    //build language detector:
                    languageDetector = LanguageDetectorBuilder.create(NgramExtractors.standard())
                            .withProfiles(languageProfiles)
                            .build();
                }
            }
        }
        return languageDetector;
    }

    private static TextObjectFactory textObjectFactory = null;

    //单例模式延迟加载获取LanguageDetect对象
    public static TextObjectFactory getTextObjectFactory() {
        if (textObjectFactory == null) {
            synchronized (FileUtils.class) {
                if (textObjectFactory == null) {
                    textObjectFactory = CommonTextObjectFactories.forDetectingOnLargeText();
                }
            }
        }
        return textObjectFactory;
    }

    //------------------------------------Excel--------------------------------------------

    /**
     * 将Excle表格写入文件中
     *
     * @param workbook
     * @param file
     */
    public static void writeExcel(Workbook workbook, File file) {
        FileOutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(file);
            workbook.write(outputStream);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (outputStream != null) {
                    outputStream.close();
                }
                if (workbook != null) {
                    workbook.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static String getCellAsString(Row row, int c, FormulaEvaluator formulaEvaluator) {
        String value = "";
        try {
            Cell cell = row.getCell(c);
            CellValue cellValue = formulaEvaluator.evaluate(cell);
            switch (cellValue.getCellType()) {
                case BOOLEAN:
                    value = "" + cellValue.getBooleanValue();
                    break;
                case NUMERIC:
                    double numericValue = cellValue.getNumberValue();
                    if (HSSFDateUtil.isCellDateFormatted(cell)) {
                        double date = cellValue.getNumberValue();
                        SimpleDateFormat formatter =
                                new SimpleDateFormat("dd/MM/yy");
                        value = formatter.format(HSSFDateUtil.getJavaDate(date));
                    } else {
                        value = "" + numericValue;
                    }
                    break;
                case STRING:
                    value = "" + cellValue.getStringValue();
                    break;
                default:
            }
        } catch (NullPointerException e) {
            /* proper error handling should be here */
            e.printStackTrace();
        }
        return value;
    }


}
